class ElementWrapper {
	constructor(type) {
		this.root = document.createElement(type);
	}

	setAttribute(name, value) {
		if (name.match(/^on([\s\S]+)$/)) {
			const eventName = RegExp.$1.replace(/^[\s\S]/, s => s.toLowerCase())
			this.root.addEventListener(eventName, value)
		}
		if (name === 'className') {
			name = 'class';
		}
		this.root.setAttribute(name, value);
	}

	// appendChild(vChild) {
	// 	vChild.mountTo(this.root);
	// }

	appendChild(vChild) {
		const range = document.createRange();
		if (this.root.children.length) {
			range.setStartAfter(this.root.lastChild)
			range.setEndAfter(this.root.lastChild)
		} else {
			range.setStart(this.root, 0)
			range.setEnd(this.root, 0)
		}
		vChild.mountTo(range)
	}

	mountTo(range) {
		range.deleteContents();
		range.insertNode(this.root);
	}
}

class TextWrapper {
	constructor(content) {
		this.root = document.createTextNode(content);
	}
	mountTo(range) {
		range.deleteContents();
		range.insertNode(this.root);
	}
}

export class Component {
	constructor() {
		this.children = [];
		this.props = Object.create(null);
		// this.LIFE_CYCLE_STATE = 'init';
	}
	setAttribute(name, value) {
		if (name.match(/^on([\s\S]+)$/)) {
			// const eventName = RegExp.$1.replace(/^[\s\S]/, s => s.toLowerCase())
			// this.root.addEventListener(eventName, value)
		}

		if (name === 'className') {
			name = 'class';
		}
		this.props[name] = value
		this[name] = value
	}
	mountTo(range) {
		// will mount
		// if (this.LIFE_CYCLE_STATE === 'init') {
		// 	if (typeof this.willMount === 'function') {
		// 		this.willMount(JSON.stringify(this.LIFE_CYCLE_STATE));
		// 	}
		// }
		this.range = range;
		this.update();
		// did mount
		// if (this.LIFE_CYCLE_STATE === 'mounted') {
		// 	if (typeof this.didMount === 'function') {
		// 		this.didMount(JSON.stringify(this.LIFE_CYCLE_STATE));
		// 	}
		// }

	}

	update() {
		let placeholder = document.createComment('placeholder');
		let range = document.createRange();
		range.setStart(this.range.endContainer, this.range.endOffset)
		range.setEnd(this.range.endContainer, this.range.endOffset);
		range.insertNode(placeholder);
		this.range.deleteContents();
		const vDom = this.render();
		vDom.mountTo(this.range);
		// if (this.LIFE_CYCLE_STATE === 'init') {
		// 	this.changeLIFE_CYCLE_STATE('mounted');
		// }
	}

	appendChild(vChild) {
		this.children.push(vChild);
	}

	setState(state) {

		if (typeof state === 'undefined') {
			return void 0;
		}

		let merge = (oldState, newState) => {
			for (const p in newState) {
				if (typeof oldState[p] === 'object') {
					if (typeof oldState[p] !== 'object') {
						oldState[p] = {}
					}
					merge(oldState[p], newState[p])
				} else {
					oldState[p] = newState[p]
				}
			}
		}
		if (!this.state && state)
			this.state = {}

		const prevState = JSON.parse(JSON.stringify(this.state));
		const nextState = merge(this.state, state);

		this.update();

		// const diff = (prevState, nextState) => {
		// 	return JSON.stringify(prevState) !== JSON.stringify(nextState)
		// }

		// if (diff(prevState, nextState)) {

		// 	if (this.LIFE_CYCLE_STATE === 'mounted') {
		// 		if (typeof this.willUpdate === 'function') {
		// 			this.willUpdate(prevState, nextState);
		// 		}
		// 	}

		// 	this.update();

		// 	if (this.LIFE_CYCLE_STATE === 'mounted') {
		// 		if (typeof this.didUpdate === 'function') {
		// 			this.didUpdate();
		// 		}
		// 	}
		// }

	}

	// changeLIFE_CYCLE_STATE(STATE) {
	// 	this.LIFE_CYCLE_STATE = STATE;
	// }
}

function render(vdom, root) {
	let range = document.createRange();
	if (root.children.length) {
		range.setStartAfter(root.lastChild);
		range.setEndAfter(root.lastChild);
	} else {
		range.setStart(root, 0);
		range.setEnd(root, 0);
	}
	vdom.mountTo(range);
}


export let ToyReact = {
	createElement(type, attributes, ...children) {
		let element;
		if (typeof type === 'string') {
			element = new ElementWrapper(type)
		} else {
			element = new type;
		}

		for (let name in attributes) {
			element.setAttribute(name, attributes[name]);
		}

		let insertChildren = (children) => {
			for (let child of children) {
				if (typeof child === 'object' && child instanceof Array) {
					insertChildren(child)
				} else {
					// 无法识别的直接转为字符串, 如:对象
					if (!(child instanceof ElementWrapper) &&
						!(child instanceof TextWrapper) &&
						!(child instanceof Component)) {
						child = String(child);
					}

					if (typeof child === 'string') {
						child = new TextWrapper(child);
					}

					element.appendChild(child)
				}
			}
		};
		insertChildren(children)
		return element;
	},
	render(vDom, element) {
		let range = document.createRange();
		if (element.children.length) {
			range.setStartAfter(element.lastChild);
			range.setEndAfter(element.lastChild);
		} else {
			range.setStart(element, 0);
			range.setEnd(element, 0);
		}
		vDom.mountTo(range);
	}
}